home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / joe014.zip / JOE014.TAZ / JOE014.tar / asyncesix.c < prev    next >
C/C++ Source or Header  |  1992-01-23  |  5KB  |  293 lines

  1. /* Terminal interface for ESIX
  2.    Copyright (C) 1991 Joseph H. Allen
  3.  
  4. This file is part of JOE (Joe's Own Editor)
  5.  
  6. JOE is free software; you can redistribute it and/or modify it under the terms
  7. of the GNU General Public License as published by the Free Software
  8. Foundation; either version 1, or (at your option) any later version. 
  9.  
  10. JOE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE.  See the GNU General Public License for more details.  
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with JOE; see the file COPYING.  If not, write to
  16. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include <stdio.h>
  19. #include <signal.h>
  20. #include <fcntl.h>
  21. #include <sys/time.h>
  22. #include <sys/param.h>
  23. #include <termio.h>
  24. #include "async.h"
  25.  
  26. struct winsize
  27. {
  28. unsigned short ws_row;
  29. unsigned short ws_col;
  30. unsigned short ws_xpixel;
  31. unsigned short ws_ypixel;
  32. };
  33.  
  34. #define DIVISOR 12000000
  35. #define TIMES 2
  36.  
  37. static struct termio oldterm;
  38.  
  39. static unsigned char *obuf=0;
  40. static unsigned obufp=0;
  41. static unsigned obufsiz;
  42. static unsigned long ccc;
  43.  
  44. static unsigned speeds[]=
  45. {
  46. B50,50,B75,75,B110,110,B134,134,B150,150,B200,200,B300,300,B600,600,B1200,1200,
  47. B1800,1800,B2400,2400,B4800,4800,B9600,9600,EXTA,19200,EXTB,38400
  48. };
  49.  
  50. void tsignal();
  51.  
  52. sigjoe()
  53. {
  54. signal(SIGHUP,tsignal);
  55. signal(SIGTERM,tsignal);
  56. signal(SIGINT,SIG_IGN);
  57. signal(SIGPIPE,SIG_IGN);
  58. signal(SIGQUIT,SIG_IGN);
  59. }
  60.  
  61. signorm()
  62. {
  63. signal(SIGHUP,SIG_DFL);
  64. signal(SIGTERM,SIG_DFL);
  65. signal(SIGINT,SIG_DFL);
  66. signal(SIGPIPE,SIG_DFL);
  67. signal(SIGQUIT,SIG_DFL);
  68. }
  69.  
  70. aopen()
  71. {
  72. int x;
  73. struct termio newterm;
  74. fflush(stdout);
  75. ioctl(fileno(stdin),TCGETA,&oldterm);
  76. newterm=oldterm;
  77. newterm.c_lflag=0;
  78. newterm.c_iflag&=~(ICRNL|IGNCR|INLCR);
  79. newterm.c_oflag=0;
  80. newterm.c_cc[VMIN]=1;
  81. newterm.c_cc[VTIME]=0;
  82. ioctl(fileno(stdin),TCSETAW,&newterm);
  83. ccc=0;
  84. for(x=0;x!=30;x+=2)
  85.  if((newterm.c_cflag&CBAUD)==speeds[x])
  86.   {
  87.   ccc=DIVISOR/speeds[x+1];
  88.   break;
  89.   }
  90. if(obuf) free(obuf);
  91. if(!(TIMES*ccc)) obufsiz=4096;
  92. else
  93.  {
  94.  obufsiz=1000000/(TIMES*ccc);
  95.  if(obufsiz>4096) obufsiz=4096;
  96.  }
  97. if(!obufsiz) obufsiz=1;
  98. obuf=(unsigned char *)malloc(obufsiz);
  99. }
  100.  
  101. aclose()
  102. {
  103. aflush();
  104. ioctl(fileno(stdin),TCSETAW,&oldterm);
  105. }
  106.  
  107. int have=0;
  108. static unsigned char havec;
  109. static int yep;
  110.  
  111. static dosig()
  112. {
  113. yep=1;
  114. }
  115.  
  116. aflush()
  117. {
  118. if(obufp)
  119.  {
  120.  struct itimerval a,b;
  121.  unsigned long usec=obufp*ccc;
  122.  if(usec>=500000/10 /* HZ */)
  123.   {
  124.   a.it_value.tv_sec=usec/1000000;
  125.   a.it_value.tv_usec=usec%1000000;
  126.   a.it_interval.tv_usec=0;
  127.   a.it_interval.tv_sec=0;
  128.   signal(SIGALRM,dosig);
  129.   yep=0;
  130.   sigsetmask(sigmask(SIGALRM));
  131.   setitimer(ITIMER_REAL,&a,&b);
  132.   write(fileno(stdout),obuf,obufp);
  133.   while(!yep) sigpause(0);
  134.   signal(SIGALRM,SIG_DFL);
  135.   }
  136.  else write(fileno(stdout),obuf,obufp);
  137.  obufp=0;
  138.  }
  139. if(!have)
  140.  {
  141.  fcntl(fileno(stdin),F_SETFL,O_NDELAY);
  142.  if(read(fileno(stdin),&havec,1)==1) have=1;
  143.  fcntl(fileno(stdin),F_SETFL,0);
  144.  }
  145. }
  146.  
  147. unsigned char *take=0;
  148.  
  149. anext()
  150. {
  151. if(take)
  152.  if(*take)
  153.   {
  154.   int c;
  155.   if(*take!='\\') return *take++;
  156.   ++take;
  157.   if(!*take) return '\\';
  158.   else if(*take=='r') c='\r';
  159.   else if(*take=='b') c=8;
  160.   else if(*take=='n') c=10;
  161.   else if(*take=='f') c=12;
  162.   else if(*take=='a') c=7;
  163.   else if(*take=='\"') c='\"';
  164.   else if(*take>='0' && *take<='7')
  165.         {
  166.         c= *take++-'0';
  167.         if(*take>='0' && *take<='7')
  168.          {
  169.          c=c*8+*take++-'0';
  170.          if(*take>='0' && *take<='7') c=c*8+*take++-'0';
  171.          }
  172.         --take;
  173.         }
  174.   else c= *take;
  175.   ++take;
  176.   return c;
  177.   }
  178.  else take=0;
  179. aflush();
  180. if(have) have=0;
  181. else if(read(fileno(stdin),&havec,1)<1) tsignal(0);
  182. if(record) macroadd(havec);
  183. return havec;
  184. }
  185.  
  186. eputc(c)
  187. unsigned char c;
  188. {
  189. obuf[obufp++]=c;
  190. if(obufp==obufsiz) aflush();
  191. }
  192.  
  193. eputs(s)
  194. char *s;
  195. {
  196. while(*s)
  197.  {
  198.  obuf[obufp++]= *(s++);
  199.  if(obufp==obufsiz) aflush();
  200.  }
  201. }
  202.  
  203. getsize()
  204. {
  205. #ifdef TIOCGSIZE
  206. struct ttysize getit;
  207. #else
  208. #ifdef TIOCGWINSZ
  209. struct winsize getit;
  210. #else
  211. char *p;
  212. #endif
  213. #endif
  214. #ifdef TIOCGSIZE
  215. if(ioctl(fileno(stdout),TIOCGSIZE,&getit)!= -1)
  216.  {
  217.  if(getit.ts_lines>=3) height=getit.ts_lines;
  218.  if(getit.ts_cols>=2) width=getit.ts_cols;
  219.  }
  220. #else
  221. #ifdef TIOCGWINSZ
  222. if(ioctl(fileno(stdout),TIOCGWINSZ,&getit)!= -1)
  223.  {
  224.  if(getit.ws_row>=3) height=getit.ws_row;
  225.  if(getit.ws_col>=2) width=getit.ws_col;
  226.  }
  227. #else
  228. if(p=getenv("ROWS")) sscanf(p,"%d",&height);
  229. if(p=getenv("COLS")) sscanf(p,"%d",&width);
  230. if(height<3) height=24;
  231. if(width<2) width=80;
  232. #endif
  233. #endif
  234. }
  235.  
  236. termtype()
  237. {
  238. unsigned char entry[1024];
  239. unsigned char area[1024];
  240. unsigned char *foo=area;
  241. unsigned char *x=(unsigned char *)getenv("TERM");
  242. if(!x) goto down;
  243. if(tgetent(entry,x)!=1) goto down;
  244. height=tgetnum("li");
  245. if(height<3) height=24;
  246. width=tgetnum("co");
  247. if(width<2) width=80;
  248. if(!tgetstr("cs",&foo)) scroll=0;
  249. down:
  250. getsize();
  251. }
  252.  
  253. shell()
  254. {
  255. int x;
  256. char *s=(char *)getenv("SHELL");
  257. if(!s)
  258.  {
  259.  puts("\nSHELL variable not set");
  260.  return;
  261.  }
  262. eputs("\nYou are at the command shell.  Type 'exit' to continue editing\r\n");
  263. aclose();
  264. if(x=fork())
  265.  {
  266.  if(x!= -1) wait(0);
  267.  }
  268. else
  269.  {
  270.  signorm();
  271.  execl(s,s,0);
  272.  _exit(0);
  273.  }
  274. aopen();
  275. }
  276.  
  277. susp()
  278. {
  279. #ifdef SIGCONT
  280. eputs("\nThe editor has been suspended.  Type 'fg' to continue editing\r\n");
  281. yep=0;
  282. aclose();
  283. signal(SIGCONT,dosig);
  284. sigsetmask(sigmask(SIGCONT));
  285. kill(0,SIGTSTP);
  286. while(!yep) sigpause(0);
  287. signal(SIGCONT,SIG_DFL);
  288. aopen();
  289. #else
  290. shell();
  291. #endif
  292. }
  293.